NOTE on a SUBmit utility for ZCPR33 for long submit files.
	by Thomas E. Croley II, 2 July 1987
		* Corrects ZCPR33 error in submit processing for $$$.SUB
			files longer than can be accessed with a single
			directory entry.
		* Requires modification of ZCPR33 CCP !!!! (see below).
		* Requires modification of submit utility, SUB34 (see below).
		* XSUB not supported (I can't get XSUB to work properly with
			the unchanged SUB34 and ZCPR33 with short submit files
			yet, let alone the changed versions with long files!)

Submit file processing is (and has always been?) limited to short *.SUB file
lengths (fewer than 128 lines for disk allocation blocks of 2k, 256 lines
for disk allocation blocks of 4k, ...).  This is because ZCPR33 finds the
last record in the $$$.SUB file for processing and attempts to close the file
one record shorter to remove that record (command) from further processing;
to do this, ZCPR33 decrements the record count in the FCB for the file before
the close.  This works if there is only one directory entry in the directory
for the $$$.SUB file but it does not work if there are more.  If you use a
disk allocation block size of 2k, then one directory entry manages 16k (one
extent) of file space (=128 records) which, at one line per record in a
$$$.SUB file, limits your submit files (*.SUB) to 128 lines.  Likewise, a 4k
block size allows one directory entry to manage 32k (two extents) of file
space (=256 records), limiting submit files to 256 lines, and so forth.
Subsequently, for longer $$$.SUB files, ZCPR33 neither finds the end of file
correctly, nor is it able to reduce the file length past the point allocated
to an earlier directory entry.  The proper way around this is to implement
direct access ("random access" in old CP/M terminology) file manipulations to
find the end of the file and to keep track of the last record processed.  The
SUB utility must be modified also to use this method so that the last record
(first command) to be accessed by the CCP is pointed to in the file (the last
record of the file is used for this purpose here).  Also, file append (for
nesting of SUB commands), must properly maintain this pointer.

If you use wish to use long submit files, you must modify BOTH the SUB
command AND your ZCPR33 CCP by changing the following code as instructed
below.

The PENALTY is that it will slow submit file processing (hardly noticeable on
a RAM disk but may be significant on a floppy) since additional disk reads
and writes are required to find and maintain the next-command pointer.  These
reads and writes are not to sequential records on the disk since the pointer
is maintained in the last record of the file while commands are taken
successively toward the beginning.

The ADVANTAGE is that it will allow arbitrary length submit files for
processing.

IF YOU DO NOT MODIFY THE SUB COMMAND AND DO NOT MODIFY YOUR ZCPR33 CCP AS
FOLLOWS, THEN _BEWARE_ THAT SUMBIT FILES WITH LINE LENGTHS EXCEEDING THE ABOVE
LIMITS WILL NOT BE POSSIBLE _AND_ THERE IS NO ERROR MESSAGE NOR ERROR CHECKING
FOR THIS CONDITION WITHIN THE CCP.

NOTE also that XSUBZ must be modified to be consistent with the new file
structure for $$$.SUB.  I spent a day trying to modify XSUBZ12 but could not
get it to work.  There are difficulties already present in XSUBZ12 since I
could not get the unmodified XSUBZ to work correctly with the unmodified
SUB34 and ZCPR33.  These difficulties should be resolved before similar
changes are made to XSUBZ to allow direct access of records.  For now, XSUBZ
or XSUB cannot be used with the modified SUB routine (nor, apparently, with
the unmodified routine either).


MODIFICATIONS TO ZCPR33.Z80 (may require reconfiguration in Z33HDR.LIB to
		make room for the additional code on your machine)

Find the label "subfcr:" in ZCPR33.Z80 and add the code denoted by ";TEC" as
follows:

subfcr:
	defs	1		; Current record number
subfr:				;TEC
	defs	3		;TEC Random record no. (16 bits) + ovrflw byte

Find the label "readbuf:" in ZCPR33.Z80 and modify or add the code as denoted
by ";TEC" as follows:

readbuf:

	ld	a,(zexrunfl)	; Get ZEX-running flag
	or	a
	jp	nz,userinput	; If ZEX running, go directly to user input

	 if	subon		; If submit facility is enabled, check for it

	ld	a,(subflag)	; Test for submit file running
	or	a
	jr	z,shellinput	; If not, go on to possible shell input

	xor	a		; Log into user 0
	call	setuser
	call	defltdma	; Initialize DMA pointer
	ld	de,subfcb	; Point to submit file FCB
	call	open		; Try to open file
	jr	z,readbuf1	; Branch if open failed

;TEC	ld	hl,subfrc	; Point to record count in submit FCB
;TEC	ld	a,(hl)		; Get the number of records in file
;TEC	dec	a		; Reduce to number of last record
;TEC	ld	(subfcr),a	; ..and put into current record field
	ld	c,23h		;TEC "Compute file size" bdos call no.
	call	bdossave	;TEC DE still => subfcb; get file size in subfr
	ld	hl,(subfr)	;TEC Get file size
	dec	hl		;TEC Decrement to get last record no.
	ld	(subfr),hl	;TEC Replace in random record field
	ld	c,21h		;TEC "Read random" bdos call no.
	call	bdossave	;TEC DE still => subfcb; randm read last record
	ld	hl,(tbuff)	;TEC Get current "last record" from last record
	dec	hl		;TEC Point to next earlier record to read
	ld	(tbuff),hl	;TEC Save pointer in actual last record
	inc	c		;TEC ... and write back to file (c=22h)
	call	bdossave	;TEC DE still => subfcb; randm write last recrd
	ld	(subfr),hl	;TEC Now prepare to read new "last record"
	dec	c		;TEC (c=21h)
	call	bdossave	;TEC Random read record; DE still => subfcb
;TEC	call	read		; Attempt to read submit file
;TEC	jr	nz,readbuf1	; Branch if read failed

;TEC	dec	(hl)		; Reduce file record cound
;TEC	dec	hl		; Point to S2 byte of FCB (yes, this is req'd!)
;TEC	ld	(hl),a		; Stuff a zero in there (A=0 from call to READ)
	ld	(subfrc-1),a	;TEC Zero FCB S2 byte (A=0 from previous read)
	call	close		; Close the submit file one record smaller
	jr	z,readbuf1	; Branch if close failed

END of ZCPR33.Z80 changes...


MODIFICATIONS TO SUB34.Z80

Find the label "wrset:" in SUB34.Z80 and modify or add the code denoted by
";TEC" as follows:

;
;	SET UP THE $$$.SUB FILE
;	FOR WRITING
;
wrset:
	call	print
	db	cr,lf,' Writing Command File to Disk',0

	ld	e,0		; Set user 0
	ld	c,20h
	call	bdos

	ld	de,subfcb
	ld	c,openf
	call	bdos		; Open the file
	inc	a		; Check cpm return
	jp	z,none1		; None exists already
;
;	$$$.SUB EXISTS, SO SET
;	FCB TO APPEND TO IT
;

	ld	de,subfcb	;TEC Point to submit file FCB
	ld	c,23h		;TEC "Compute file size" bdos call no.
	call	bdos		;TEC Get file size in subfr
	ld	hl,(subfr)	;TEC Get file size
	dec	hl		;TEC Decrement to get last record no.
	ld	(oldfsz),hl	;TEC Save present file last record no.
	ld	(subfr),hl	;TEC Replace in random record field
	ld	de,subfcb	;TEC Point to submit file FCB again
	ld	c,21h		;TEC "Read random" bdos call no.
	call	bdos		;TEC Random read last record
	ld	hl,(tbuf)	;TEC Get current "last record" pointer
	dec	hl		;TEC Decr. to point to last unprocessed record
	ld	(subfr),hl	;TEC Now read "last record"
	ld	de,subfcb	;TEC Point to submit file FCB again
	ld	c,21h		;TEC "Read random" bdos call no.
	call	bdos		;TEC Random read record
	ld	de,subfcb	;TEC Prepare for sequential (re)write to update
	ld	c,15h		;TEC ... DOS pointers for further writes
	call	bdos		;TEC Write same info back to set DOS pointers
;TEC	ld	a,(subfcb+fcbrc) ; Get record count
;TEC	ld	(subfcb+fcbnr),a ; Make next record
	ret
oldfsz:	ds	2		;TEC space for "old file size"
;
;	COME HERE WHEN NO $$$.SUB EXISTS
;
none1:
	xor	a		;TEC
	ld	(oldfsz),a	;TEC Zero "old file size" since it did'nt exist
	ld	(oldfsz+1),a	;TEC
	ld	de,subfcb
	ld	c,makef
	call	bdos
	inc	a
	jp	z,nomake	; 0ffh=can't create file
	ret

Find the label "close:" in SUB34.Z80 and add the code denoted by ";TEC" as
follows:

;
;	$$$.SUB IS WRITTEN, CLOSE THE FILE
;
close:
	ld	de,subfcb	;TEC
	ld	c,24h		;TEC Set random record number for record after
	call	bdos		;TEC ... last write
	ld	hl,(subfr)	;TEC Get rndm record no. for last record write
	ld	(tbuf),hl	;TEC Place in write buffer
	ld	de,(oldfsz)	;TEC DE = old last record number
	xor	a		;TEC Clear carry bit
	sbc	hl,de		;TEC Is new last record number >= old?
	jr	nc,nfeok	;TEC New file end O.K.
	ld	(subfr),de	;TEC ... else use old last record number
nfeok:	ld	de,subfcb	;TEC
	ld	c,22h		;TEC "Write random" bdos call no.
	call	bdos		;TEC Write current record no. to last record.
	ld	de,subfcb
	ld	c,closef
	jp	bdos

Find the label "subfcb:" in SUB34.Z80 and modify or add the code denoted by
";TEC" as follows:

;
;
;	FCB FOR $$$.SUB
;
subfcb:
	db	1		; Drive specifier (a selected)
	db	'$$$     '
subtyp:
	db	'SUB'
	dw	0,0,0,0		; Initialize rest of fcb
	dw	0,0,0,0
;TEC	dw	0,0,0,0
	dw	0,0		;TEC
	db	0		;TEC
subfr:	dw	0		;TEC Direct-access 16-bit record number
	db	0		;TEC Overflow byte
;
clbuf:	ds	2		; Ptr to command line buffer
fremem:	ds	2		; Ptr to free memory area
;
	end

END of SUB34.Z80 changes...


END OF NOTE on a SUBmit utility for ZCPR33 for long submit files.
